/*
 * @FileName: easy_serial.h
 * @Author: GreyQiu qiushaogui@aikosolar.com
 * @Date: 2023-08-21 16:44:51
 * @LastEditors: GreyQiu qiushaogui@aikosolar.com
 * @LastEditTime: 2023-09-14 10:38:21
 * @Description: 
 * 
 * Copyright (c) 2023, All Rights Reserved. 
 */

#ifndef __EASY_SERIAL_H__
#define __EASY_SERIAL_H__

#include <stdint.h>
#include <stdbool.h>

//  包固定长度
#define PKG_LEN    48

//  帧头帧尾
#define PKG_HEADER    0x7E
#define PKG_TAIL      0x7E

// 各字段位置定义
#define IDX_HEADER              0   // 头
#define IDX_DEVICE_ID_H         1   // 设备码高8位
#define IDX_DEVICE_ID_L         2   // 设备码低8位
#define IDX_CMD                 3   // 命令码
#define IDX_RW                  4   // 读写码
#define IDX_DATA_LEN_H          5   // 数据长度高8位
#define IDX_DATA_LEN_L          6   // 数据长度低8位
#define IDX_VAILD_DATA          7   // 有效数据
#define IDX_CRC16_H             45  // CRC校验码高8位
#define IDX_CRC16_L             46  // CRC校验码低8位
#define IDX_TAIL                47  // 尾

// 操作码
#define OPERATE_R       0x01   // 读
#define OPERATE_W       0x02   // 写

// 操作结果
#define ACK_SUCCESS         0
#define ACK_ERROR           1

// 读写权限
#define PERMISSION_R      1   // 只读
#define PERMISSION_W      2   // 只写
#define PERMISSION_RW     3   // 可读写

typedef struct
{
    uint16_t cmd;    // 命令码
    uint16_t permission; // 读写权限
    uint16_t len; // 可读写的长度
    void (*handler)(uint16_t cmd, uint16_t * buf, uint16_t len, uint16_t rw);
} cmd_obj_t;

void easy_serial_ack(uint16_t cmd, uint16_t ack_code, uint16_t * data, uint16_t len);
void easy_serial_process(uint16_t * buffer, uint32_t len, cmd_obj_t * cmd_tbl, uint16_t tbl_len);
#endif // __EASY_SERIAL_H__
